/**
 * -----Tag folder-----
 * http://code.google.com/p/tagfolder
 * Licensed under LGPL
 * chuanshenglu@gmail.com
 * xrjieyee@gmail.com
 *
 */
#ifndef DLEXPORT
#  define DLEXPORT
#endif

#include <windows.h>
#include "client_stub.h"
#include "client_stub_impl.h"
#include <stdio.h>

#ifdef __cplusplus
extern "C"{
#endif
BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
{
	switch( ul_reason_for_call ) 
	{
	case DLL_PROCESS_ATTACH:
		break;
	case DLL_THREAD_ATTACH:
		break;
	case DLL_THREAD_DETACH:
		break;
	case DLL_PROCESS_DETACH:
		break;
	}
	return TRUE;
}
	
//Interfaces
DL_DECL int AddTagA(const char *tag)
{
	if( tag==NULL )
	{
		return -1;
	}
	TFMessage msg;
	msg.ID = TFMSG_ADDTAG;
	msg.NextSize = ( (unsigned long)strlen(tag) + 1 ) * sizeof(char);
	if( !SendCommand(msg) || !SendData((void *)tag, msg.NextSize) )
	{
		return -1;
	}
	return 0;
}

DL_DECL int AddTagW(const wchar_t *tag)
{
	if( tag==NULL )
	{
		return -1;
	}
	TFMessage msg;
	msg.ID = TFMSG_ADDTAG;
	msg.NextSize = ( (unsigned long)wcslen(tag) + 1) * sizeof(wchar_t);
	if( !SendCommand(msg) || !SendData((void*)tag, msg.NextSize) )
	{
		return -1;
	}
	return 0;
}

DL_DECL int LinkTagToFileA(const char* tag, const char* file)
{
	if( tag==NULL || file==NULL )
	{
		return -1;
	}
	TFMessage msg;
	msg.ID = TFMSG_LINKTAGTOFILE;
	msg.NextSize = ( (unsigned long)strlen(tag) + 1) * sizeof(char);
	msg.NextSize2 = ( (unsigned long)strlen(tag) + 1) * sizeof(char);
	if( !SendCommand(msg)
	    || !SendData( (void*)tag, msg.NextSize) 
	    || !SendData( (void*)file, msg.NextSize2) )
	{
		return -1;
	}
	return 0;
}

DL_DECL int LinkTagToFileW(const wchar_t* tag, const wchar_t* file)
{
	if( tag==NULL || file==NULL )
	{
		return -1;
	}
	TFMessage msg;
	msg.ID = TFMSG_LINKTAGTOFILE;
	msg.NextSize = ( (unsigned long)wcslen(tag) + 1) * sizeof(wchar_t);
	msg.NextSize2 = ( (unsigned long)wcslen(file) + 1) * sizeof(wchar_t);
	if( !SendCommand(msg)
	    || !SendData((void*)tag, msg.NextSize) 
	    || !SendData((void*)file, msg.NextSize2) )
	{
		return -1;
	}
	return 0;
}

#ifdef __cplusplus
}
#endif
//==========================================
//Interfaces for CPP
//==========================================
#ifdef __cplusplus

DL_DECL bool AddTag(const char* tag)
{
	if( tag==NULL )
	{
		return false;
	}
	if( 0==AddTagA(tag) )
	{
		return true;
	}
	else
	{
		return false;
	}
}

DL_DECL bool AddTag(const wchar_t* tag)
{
	if( tag==NULL )
	{
		return false;
	}
	if( 0==AddTagW(tag) )
	{
		return true;
	}
	else
	{
		return false;
	}
}

DL_DECL bool AddTag(std::string &tag)
{
	return AddTag(tag.c_str());
}

DL_DECL bool AddFile(const char* file)
{
	if( file==NULL )
	{
		return false;
	}
	TFMessage msg;
	msg.ID=TFMSG_ADDFILE;
	msg.NextSize= ( (unsigned long)strlen(file) + 1) * sizeof(char);
	if( !SendCommand(msg) || !SendData((void *)file, msg.NextSize) )
	{
		return false;
	}
	return true;
}

DL_DECL bool AddFile(const wchar_t* file)
{
	if( file==NULL )
	{
		return false;
	}
	TFMessage msg;
	msg.ID=TFMSG_ADDFILE;
	msg.NextSize= ( (unsigned long)wcslen(file) + 1 ) * sizeof(wchar_t);
	if( !SendCommand(msg) || !SendData((void *)file, msg.NextSize) )
	{
		return false;
	}
	return true;
}

DL_DECL bool AddFile(std::string &file)
{
	return AddFile(file.c_str());
}

DL_DECL bool LinkTagToFile(const char* tag, const char* file){
	if( tag==NULL || file==NULL )
	{
		return false;
	}
	if( 0==LinkTagToFileA(tag,file) )
	{
		return true;
	}
	else
	{
		return false;
	}
}

DL_DECL bool LinkTagToFile(const wchar_t* tag,const wchar_t* file){
	if( tag==NULL || file==NULL )
	{
		return false;
	}
	if( 0==LinkTagToFileW(tag,file) )
	{
		return true;
	}
	else
	{
		return false;
	}
}

DL_DECL bool LinkTagToFile(std::string & tag, std::string & file)
{
	return LinkTagToFile(tag.c_str(), file.c_str());
}

DL_DECL std::set<std::string> GetAllTags()
{
	std::set<std::string> st;
	st.clear();
	TFMessage msg;
	msg.ID = TFMSG_GETALLTAGS;
	if( SendCommand(msg) )
	{
		msg = ReceiveCommand();
		for( int i=0; i<msg.NextSize; ++i)
		{
			st.insert( ReceiveString() );
		}
	}
	return st;
}

DL_DECL std::set<std::string> GetTagsOfFile(std::string &file)
{
	std::set<std::string> st;
	TFMessage msg;
	msg.ID = TFMSG_GETTAGSOFFILE;
	if( SendCommand(msg) )
	{
		msg = ReceiveCommand();
		for(int i=0; i<msg.NextSize; ++i)
		{
			st.insert( ReceiveString() );
		}
	}
	return st;
}

DL_DECL std::set<std::string> GetAllFiles()
{
	std::set<std::string> st;
	TFMessage msg;
	msg.ID = TFMSG_GETALLFILES;
	if( SendCommand(msg) )
	{
		msg = ReceiveCommand();
		for(int i=0; i<msg.NextSize; ++i)
		{
			st.insert( ReceiveString() );
		}
	}
	return st;
}

DL_DECL std::set<std::string> GetFilesWithTag(std::string &tag)
{
	std::set<std::string> st;
	TFMessage msg;
	msg.ID = TFMSG_GETFILESWITHTAG;
	if( SendCommand(msg) )
	{
		msg = ReceiveCommand();
		for(int i=0; i<msg.NextSize; ++i)
		{
			st.insert( ReceiveString() );
		}
	}
	return st;
}

#endif
